#pragma once

#include "GeneralizationSet.h"

#include "Classifier.h"
#include "Generalization.h"

namespace uml {

const bool GeneralizationSet::isCovering_default_ = false;
const bool GeneralizationSet::isDisjoint_default_ = false;
GeneralizationSet::GeneralizationSet(const QString& umlType)
    : PackageableElement(umlType) {}

void GeneralizationSet::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    PackageableElement::fromJson(json, errorList);
    JsonSerializable::fromJsonArray(generalizations_, "generalizations", json, errorList);
    isCovering_ = json.value("isCovering").toBool(isCovering_default_);
    isDisjoint_ = json.value("isDisjoint").toBool(isDisjoint_default_);
    powertype_ = JsonSerializable::create<Classifier>(json.value("powertype"), errorList);

}

void GeneralizationSet::toJson(QJsonObject& json) {
    PackageableElement::toJson(json);
    JsonSerializable::toJsonArray(generalizations_, "generalizations", json);
    if (isCovering_ != isCovering_default_) {
        json.insert("isCovering", isCovering_);
    }
    if (isDisjoint_ != isDisjoint_default_) {
        json.insert("isDisjoint", isDisjoint_);
    }
    if (powertype_) {
        QJsonObject powertype_json;
        powertype_->toJson(powertype_json);
        json.insert("powertype", powertype_json);
    }
}

/// <summary>
/// generalizations getter
/// Designates the instances of Generalization that are members of this
/// GeneralizationSet.
/// </summary>
vector<shared_ptr<Generalization>>& GeneralizationSet::generalizations() {
    return generalizations_;
}

/// <summary>
/// isCovering getter
/// Indicates (via the associated Generalizations) whether or not the set of
/// specific Classifiers are covering for a particular general classifier. When
/// isCovering is true, every instance of a particular general Classifier is also an
/// instance of at least one of its specific Classifiers for the GeneralizationSet.
/// When isCovering is false, there are one or more instances of the particular
/// general Classifier that are not instances of at least one of its specific
/// Classifiers defined for the GeneralizationSet.
/// </summary>
bool GeneralizationSet::isCovering() const {
    return isCovering_;
}

/// <summary>
/// isCovering setter
/// Indicates (via the associated Generalizations) whether or not the set of
/// specific Classifiers are covering for a particular general classifier. When
/// isCovering is true, every instance of a particular general Classifier is also an
/// instance of at least one of its specific Classifiers for the GeneralizationSet.
/// When isCovering is false, there are one or more instances of the particular
/// general Classifier that are not instances of at least one of its specific
/// Classifiers defined for the GeneralizationSet.
/// </summary>
void GeneralizationSet::setIsCovering(bool value) {
    isCovering_ = value;
}

/// <summary>
/// isDisjoint getter
/// Indicates whether or not the set of specific Classifiers in a Generalization
/// relationship have instance in common. If isDisjoint is true, the specific
/// Classifiers for a particular GeneralizationSet have no members in common; that
/// is, their intersection is empty. If isDisjoint is false, the specific
/// Classifiers in a particular GeneralizationSet have one or more members in
/// common; that is, their intersection is not empty.
/// </summary>
bool GeneralizationSet::isDisjoint() const {
    return isDisjoint_;
}

/// <summary>
/// isDisjoint setter
/// Indicates whether or not the set of specific Classifiers in a Generalization
/// relationship have instance in common. If isDisjoint is true, the specific
/// Classifiers for a particular GeneralizationSet have no members in common; that
/// is, their intersection is empty. If isDisjoint is false, the specific
/// Classifiers in a particular GeneralizationSet have one or more members in
/// common; that is, their intersection is not empty.
/// </summary>
void GeneralizationSet::setIsDisjoint(bool value) {
    isDisjoint_ = value;
}

/// <summary>
/// powertype getter
/// Designates the Classifier that is defined as the power type for the associated
/// GeneralizationSet, if there is one.
/// </summary>
shared_ptr<Classifier> GeneralizationSet::powertype() const {
    return powertype_;
}

/// <summary>
/// powertype setter
/// Designates the Classifier that is defined as the power type for the associated
/// GeneralizationSet, if there is one.
/// </summary>
void GeneralizationSet::setPowertype(shared_ptr<Classifier> value) {
    powertype_ = value;
}

} // namespace uml
